package hn.cch.grammar.java;

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * java.time.*
 * jdk >= 1.8
 * java.time.LocalDate;
 * java.time.LocalTime;
 * java.time.LocalDateTime;
 * java.time.format.DateTimeFormatter;
 */
public class TimeTest {

    private static final Logger logger = LoggerFactory.getLogger(TimeTest.class);

    @Test
    public void testLocalDate() {
        LocalDate localDate = LocalDate.now();
        LocalDateTime localDateTime = localDate.atStartOfDay();
    }


    @Test
    public void testDuration() throws InterruptedException {
        LocalDateTime startDateTime = LocalDateTime.now();
        Thread.sleep(10);
        LocalDateTime endDateTime = LocalDateTime.now();
        Duration duration = Duration.between(startDateTime, endDateTime);
        logger.info("duration:{}ms", duration.toMillis());

    }

    public Date toDate(LocalDateTime localDateTime) {
        // LocalDate localDate = LocalDate.now();
        // LocalDateTime localDateTime = localDate.atStartOfDay();
        Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
        return Date.from(instant);
    }

    public LocalDateTime fromDate(Date date) {

        LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
        return localDateTime;
    }


    /**
     * 获取区间内所有的周几
     *
     * @param dayOfWeek
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<LocalDate> getWeekList(DayOfWeek dayOfWeek, LocalDate startDate, LocalDate endDate) {
        List<LocalDate> localDateList = new ArrayList<>();
        LocalDate localDate = startDate.with(dayOfWeek);
        if (startDate.compareTo(localDate) > 0) {// 开始日期在本周周几之后就选取下周周几
            localDate = localDate.plusWeeks(1);
        }
        while (localDate.compareTo(endDate) <= 0) {// 要在结束日期之前
            localDateList.add(localDate);
            localDate = localDate.plusWeeks(1);// 添加之后计算下周
        }
        return localDateList;
    }

    /**
     * 获取区间内所有月末
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<LocalDate> getAllLastDayOfMonth(LocalDate startDate, LocalDate endDate) {
        List<LocalDate> localDateList = new ArrayList<>();
        LocalDate localDate = startDate.with(TemporalAdjusters.lastDayOfMonth());// 计算开始日期当月月末
        while (localDate.compareTo(endDate) <= 0) {// 要在结束日期之前
            localDateList.add(localDate);
            localDate = localDate.plusMonths(1).with(TemporalAdjusters.lastDayOfMonth());// 计算下月月末
        }
        return localDateList;
    }


    public static void test() {


        DateTimeFormatter dfp = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate localDate0 = LocalDate.parse("2021-09-27", dfp);
        LocalDate localDate1 = LocalDate.parse("2021-09-27", dfp);
        // 前大于后=1， 前等于后=0，前小于后=-1
        logger.info("compareTo:" + localDate0.compareTo(localDate1));

        // LocalDateTime格式转换必须是完整的日期或时间，不能缺省
        // dfp = DateTimeFormatter.ofPattern("yyyyMM");
        // LocalDate localDate2 = LocalDate.parse("202202", dfp);
        // logger.info(localDate2.toString());


        LocalDate monday = localDate0.with(WeekFields.ISO.dayOfWeek(), 1L);


    }

    @Test
    public void demo() {

        DateTimeFormatter dfp = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime localDateTime = LocalDateTime.parse("2021-09-26 19:56:38", dfp);

        logger.info("year:" + localDateTime.getYear());
        logger.info("month:" + localDateTime.getMonthValue());
        logger.info("week:" + localDateTime.getDayOfWeek().getValue());// 1是周一，7是周天
        logger.info("day:" + localDateTime.getDayOfMonth());
        LocalDate localDate = LocalDate.of(localDateTime.getYear(), localDateTime.getMonthValue(), localDateTime.getDayOfMonth());
        date(localDate);


        logger.info("hour:" + localDateTime.getHour());
        logger.info("minute:" + localDateTime.getMinute());
        logger.info("second:" + localDateTime.getSecond());
        logger.info("nano:" + localDateTime.getNano());
        LocalTime localTime = LocalTime.of(localDateTime.getHour(), localDateTime.getMinute(), localDateTime.getSecond());
        time(localTime);

    }


    public static void date(LocalDate localDate) {
        //
        LocalDate localDateDay = localDate.plusDays(1);
        LocalDate localDateWeek = localDate.plusWeeks(1);
        LocalDate localDateMonth = localDate.plusMonths(1);
        LocalDate localDateYear = localDate.plusYears(1);

        // localDate.withDayOfMonth(17);
        // localDate.withDayOfYear();
        // localDate.withMonth();
        // localDate.withYear();
    }


    public static void time(LocalTime localTime) {


        LocalTime localTimeHour = localTime.plusHours(1);
        LocalTime localTimeMinute = localTime.plusMinutes(1);
        LocalTime localTimeSecond = localTime.plusSeconds(1);
        LocalTime localTimeNano = localTime.plusNanos(1);

        // localTime.withHour();
        // localTime.withMinute();
        // localTime.withSecond();
        // localTime.withNano();
    }

    @Test
    public void testQuarter() {
        LocalDate now = LocalDate.now();
        Month month = now.getMonth().firstMonthOfQuarter(); // 当季首月在同一年
        // 上季末最后一个自然日
        LocalDate lastQuarterEnd = LocalDate.of(now.getYear(), month, 1).minusDays(1);
        logger.info("{}", lastQuarterEnd);
        LocalDate lastLastQuarterEnd = lastQuarterEnd.minusMonths(2).withDayOfMonth(1).minusDays(1);
        logger.info("{}", lastLastQuarterEnd);


    }

}
